package com.example.compare;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;

import static com.example.compare.PeopleInfoForJson.Phone.PhoneType.MP;

public class Compare {
    private static int TEST_COUNT = 100000;

    public static void main(String[] args) throws InvalidProtocolBufferException, JsonProcessingException {

        int count;
        byte[] pbBytes = new byte[0];
        String jsonStr = null;
        ObjectMapper objectMapper = new ObjectMapper();

        // ------------------------------Protobuf 序列化 -----------------------------------
        {
            PeopleInfo peopleInfo = buildPeopleInfo();
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 序列化count次
            while ((count--) > 0) {
                pbBytes = peopleInfo.toByteArray();
            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [pb序列化]耗时：%dms, 序列化后的大小: %d\n",
                    TEST_COUNT, etime-stime, pbBytes.length);
        }

        // ------------------------------Protobuf 反序列化 ---------------------------------
        {
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 反序列化count次
            while ((count--) > 0) {
                PeopleInfo.parseFrom(pbBytes);
            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [pb反序列化]耗时：%dms\n",
                    TEST_COUNT, etime-stime);
        }

        // ---------------------------- fastjson2 序列化 ------------------------------------
        {
            PeopleInfoForJson peopleInfoForJson = buildPeopleInfoForJson();
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 序列化count次
            while ((count--) > 0) {
                jsonStr = JSON.toJSONString(peopleInfoForJson);
                //JSON.toJSONString(peopleInfoForJson);

            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [fastjson2序列化]耗时：%dms, 序列化后的大小: %d\n",
                    TEST_COUNT, etime-stime, jsonStr.length());
        }

        // --------------------------- fastjson2 反序列化 -----------------------------------
        {
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 反序列化count次
            while ((count--) > 0) {
                JSON.parseObject(jsonStr, PeopleInfoForJson.class);
            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [fastjson2反序列化]耗时：%dms\n",
                    TEST_COUNT, etime-stime);
        }

        // ------------------------------jackson 序列化 ---------------------------------------
        {
            PeopleInfoForJson peopleInfoForJson = buildPeopleInfoForJson();
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 序列化count次
            while ((count--) > 0) {
                jsonStr = objectMapper.writeValueAsString(peopleInfoForJson);
            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [jackson序列化]耗时：%dms, 序列化后的大小: %d\n",
                    TEST_COUNT, etime-stime, jsonStr.length());
        }

        // ------------------------------jackson 反序列化 -------------------------------------
        {
            count = TEST_COUNT;
            long stime = System.currentTimeMillis();
            // 反序列化count次
            while ((count--) > 0) {
                objectMapper.readValue(jsonStr, PeopleInfoForJson.class);
            }
            long etime = System.currentTimeMillis();
            System.out.printf("%d次 [jackson反序列化]耗时：%dms\n",
                    TEST_COUNT, etime-stime);
        }
    }

    private static PeopleInfo buildPeopleInfo() {
        PeopleInfo.Builder peopleBuilder = PeopleInfo.newBuilder();
        peopleBuilder.setName("张珊");
        peopleBuilder.setAge(20);
        peopleBuilder.setQq("95991122");
        for(int i = 0; i < 5; i++) {
            PeopleInfo.Phone.Builder phoneBuild = PeopleInfo.Phone.newBuilder();
            phoneBuild.setNumber("110112119");
            phoneBuild.setType(PeopleInfo.Phone.PhoneType.MP);
        }
        com.example.proto3.Address.Builder addressBuilder = com.example.proto3.Address.newBuilder();
        addressBuilder.setHomeAddress("陕西省西安市长安区");
        addressBuilder.setUnitAddress("陕西省西安市雁塔区");
        peopleBuilder.setData(Any.pack(addressBuilder.build()));
        peopleBuilder.putRemark("key1", "value1");
        peopleBuilder.putRemark("key2", "value2");
        peopleBuilder.putRemark("key3", "value3");
        peopleBuilder.putRemark("key4", "value4");
        peopleBuilder.putRemark("key5", "value5");
        return peopleBuilder.build();
    }

    private static PeopleInfoForJson buildPeopleInfoForJson() {
        PeopleInfoForJson peopleInfo = new PeopleInfoForJson();
        peopleInfo.setName("张珊");
        peopleInfo.setAge(20);
        peopleInfo.setQq("95991122");
        for(int i = 0; i < 5; i++) {
            PeopleInfoForJson.Phone phone = new PeopleInfoForJson.Phone();
            phone.setNumber("110112119");
            phone.setType(MP);
            peopleInfo.getPhones().add(phone);
        }
        PeopleInfoForJson.Address address = new PeopleInfoForJson.Address();
        address.setHomeAddress("陕西省西安市长安区");
        address.setUnitAddress("陕西省西安市雁塔区");
        peopleInfo.setAddress(address);
        peopleInfo.getRemark().put("key1", "value1");
        peopleInfo.getRemark().put("key2", "value2");
        peopleInfo.getRemark().put("key3", "value3");
        peopleInfo.getRemark().put("key4", "value4");
        peopleInfo.getRemark().put("key5", "value5");
        return peopleInfo;
    }
}